package livingarea.actions_impl;

import livingarea.Members.Factory.AreaMemberFactory;
import livingarea.Members.Factory.GreeneryFactory;
import livingarea.Members.Greenery;
import livingarea.Members.NonLivingMember;
import livingarea.Members.Position;
import livingarea.actions.SpawnType;
import livingarea.other.Coordinates;
import livingarea.other.Direction;
import livingarea.other.Random;

/**
 *
 * @author Muzalevskiy Vitaliy
 */
public class GreenerySpawn implements SpawnType {
    
    /**<code> AreaMember </code> object that delegate object of current class.*/
    private NonLivingMember member;
    
    /**
     * Constructor for current class.
     *
     * @param member - <code> AreaMember </code> object that delegate object of 
     *      current class.
     */
    public GreenerySpawn(NonLivingMember member){
        this.member = member;
    }

    /**
     * Current method make pray beast to spawn after specified number of
     * iterations.
     */
    @Override
    public void spawn() {
        if((member.getLifeCount() != 0) && (member.getLifeCount() % Greenery.CYCLES_TO_SPAWN) == 0){
            AreaMemberFactory greeneryFactory = new GreeneryFactory();
            greeneryFactory.create(member.getLivingArea(), createPosition());
            member.getLivingArea().getStatistics().increaseGreeneryCount();
        }  
    }
    
    private Position createPosition(){
        Position position;
        int value = getRandomValue();
        Direction direction = Coordinates.DIRECTIONS[value];
        int step = getRandomStep();
        int x = 0;
        int y = 0;
        switch (direction) {
            case NORTH:
                if (member.getPosition().getY() <= member.getLivingArea()
                        .getCoordinates().getHeight() - step) {
                    x = member.getPosition().getX();
                    y = member.getPosition().getY() + step;
                }
                break;
            case SOUTH:
                if (member.getPosition().getY() >= step) {
                    x = member.getPosition().getX();
                    y = member.getPosition().getY() - step;
                }
                break;
            case NORTH_EAST:
                if (member.getPosition().getX() <= member.getLivingArea()
                        .getCoordinates().getLength() - step
                        && member.getPosition().getY() <= member.getLivingArea()
                        .getCoordinates().getHeight() - step/2) {
                    
                    if ((member.getPosition().getX() % 2) == 0
                            || member.getPosition().getX() == 0) {
                        y = member.getPosition().getY() + step/2;
                    } else {
                        y = member.getPosition().getY() + step/2 + 1;
                    }
                    x = member.getPosition().getX() + step;

                }
                break;
            case NORTH_WEST:
                if (member.getPosition().getX() >= step                         
                        && member.getPosition().getY() <= member.getLivingArea()
                        .getCoordinates().getHeight() - step/2) {
                    if ((member.getPosition().getX() % 2) == 0
                            || member.getPosition().getX() == 0) {
                        y = member.getPosition().getY() + step/2;
                    } else {
                        y = member.getPosition().getY() + step/2 + 1;
                    }
                    x = member.getPosition().getX() - step;
                }
                break;
            case SOUTH_EAST:
                if (member.getPosition().getX() <= member.getLivingArea()
                        .getCoordinates().getLength() - step                        
                        && member.getPosition().getY() >= step/2) {
                    if ((member.getPosition().getX() % 2) == 0
                            || member.getPosition().getX() == 0) {
                        y = member.getPosition().getY() - step/2 - 1;
                    } else {
                        y = member.getPosition().getY() - step/2;
                    }
                    x = member.getPosition().getX() + step;
                }
                break;
            case SOUTH_WEST:
                if (member.getPosition().getX() >= step                        
                        && member.getPosition().getY() >= step/2) {
                    if ((member.getPosition().getX() % 2) == 0
                            || member.getPosition().getX() == 0) {
                        y = member.getPosition().getY() - step/2 - 1;
                    } else {
                        y = member.getPosition().getY() - step/2;
                    }
                    x = member.getPosition().getX() - step;
                }
                break;
            default:
                throw new RuntimeException();
        }
        position = new Position(x, y);
        return position;
    }
    
    public int getRandomValue() {
        return (int) (new Random().getRandomValue(Coordinates.DIRECTIONS.length));
    }

    public int getRandomStep() {
        return (int) (new Random().getRandomValue(Greenery.MAX_SPAWN_RADIUS));
    }
}
